home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / extras / programm / gemfsc20 / gemfsc20.lzh / EXAMPLES / BROWSE / DLLUTIL.C < prev    next >
Text File  |  1992-12-07  |  5KB  |  208 lines

  1. /*****************************************************************************
  2.  * DLLUTIL - Standard routines for handling double-linked lists.
  3.  ****************************************************************************/
  4.  
  5. #define DLLUTIL_INTERNALS
  6. #include "dllutil.h"
  7.  
  8. #ifndef NULL
  9.   #define NULL ((void*)0)
  10. #endif
  11.  
  12. #ifndef TRUE
  13.   #define TRUE    1
  14.   #define FALSE 0
  15. #endif
  16.  
  17. #define DLL_DEBUG(statement)  /* statement */
  18.  
  19. void *dl_insert(list, afteritem, newitem)
  20. /*****************************************************************************
  21.  *
  22.  ****************************************************************************/
  23.     register DlList    *list;
  24.     register DllHeader *afteritem;
  25.     register DllHeader *newitem;
  26. {
  27.     if (NULL == list || NULL == afteritem || NULL == newitem) {
  28.         DLL_DEBUG(printf("NULL item pointer: dl_insert(%p, %p, %p);\n", list, afteritem, newitem));
  29.         return NULL;
  30.     }
  31.  
  32.     newitem->prev    = afteritem;
  33.     newitem->next    = afteritem->next;
  34.     afteritem->next = newitem;
  35.  
  36.     if (NULL == newitem->next) {
  37.         list->tail = newitem;
  38.     } else {
  39.         newitem->next->prev = newitem;
  40.     }
  41.     return newitem;
  42. }
  43.  
  44. void *dl_addhead(list, item)
  45. /*****************************************************************************
  46.  *
  47.  ****************************************************************************/
  48.     register DlList    *list;
  49.     register DllHeader *item;
  50. {
  51.     if (NULL == list || NULL == item) {
  52.         DLL_DEBUG(printf("NULL list or item pointer: dl_addhead(%p, %p);\n", list, item));
  53.         return NULL;
  54.     }
  55.  
  56.     item->prev = NULL;            /* first item in list has NULL backlink     */
  57.     item->next = list->head;    /* connect item's fwdlink to next item      */
  58.     list->head = item;            /* connect item to list head                */
  59.  
  60.     if (NULL == item->next) {    /* if the item we just added is last/only    */
  61.         list->tail = item;        /* item, connect it to the list tail        */
  62.         list->cur  = item;        /* and to the current-item pointer            */
  63.     } else {
  64.         item->next->prev = item;/* else connect next item's backlink        */
  65.     }
  66.  
  67.     return item;
  68. }
  69.  
  70. void *dl_addtail(list, item)
  71. /*****************************************************************************
  72.  *
  73.  ****************************************************************************/
  74.     register DlList    *list;
  75.     register DllHeader *item;
  76. {
  77.     if (NULL == list || NULL == item) {
  78.         DLL_DEBUG(printf("NULL list or item pointer: dl_addtail(%p, %p);\n", list, item));
  79.         return NULL;
  80.     }
  81.  
  82.     if (NULL == list->tail) {
  83.         return dl_addhead(list, item);
  84.     } else {
  85.         return dl_insert(list, list->tail, item);
  86.     }
  87.  
  88. }
  89.  
  90. void dl_remove(list, item)
  91. /*****************************************************************************
  92.  *
  93.  ****************************************************************************/
  94.     register DlList    *list;
  95.     register DllHeader *item;
  96. {
  97.     if (NULL == list || NULL == item) {
  98.         DLL_DEBUG(printf("NULL list or item pointer: dl_remove(%p, %p);\n", list, item));
  99.         return;
  100.     }
  101.  
  102.     if (list->cur == item) {
  103.         if (NULL == item->next) {
  104.             list->cur = item->prev;
  105.         } else {
  106.             list->cur = item->next;
  107.         }
  108.     }
  109.  
  110.     if (NULL == item->next) {
  111.         list->tail = item->prev;
  112.     } else {
  113.         item->next->prev = item->prev;
  114.     }
  115.  
  116.     if (NULL == item->prev) {
  117.         list->head = item->next;
  118.     } else {
  119.         item->prev->next = item->next;
  120.     }
  121.  
  122. }
  123.  
  124. void dl_freelist(list, freefunc)
  125. /*****************************************************************************
  126.  *
  127.  ****************************************************************************/
  128.     register DlList      *list;
  129. #if __STDC__
  130.     register void         (*freefunc)(DlList *, void *);
  131. #else
  132.     register void         (*freefunc)();
  133. #endif
  134. {
  135.     register DllHeader     *cur, *next;
  136.  
  137.     for (cur = list->head; cur != NULL; cur = next) {
  138.         next = cur->next;
  139.         (*freefunc)(list, cur);
  140.     }
  141. }
  142.  
  143. int dl_seek(list, count, whence)
  144. /*****************************************************************************
  145.  * seek to an item in a list, kinda like fseek().
  146.  * returns TRUE if at either end of the list, FALSE if not at end.
  147.  ****************************************************************************/
  148.     register DlList *list;
  149.     register long    count;
  150.     int             whence;
  151. {
  152.     register DllHeader    *cur, *next;
  153.     register int        backwards;
  154.  
  155.     switch (whence) {
  156.       case 0:
  157.         cur = list->head;
  158.         backwards = FALSE;
  159.         break;
  160.       default:
  161.         DLL_DEBUG(printf("Unknown 'whence' type in dl_seek(), SEEK_CUR assumed.\n"));
  162.         /* fall thru */
  163.       case 1:
  164.         cur = list->cur;
  165.         backwards = (count < 0) ? TRUE : FALSE;
  166.         break;
  167.       case 2:
  168.         cur = list->tail;
  169.         backwards = TRUE;
  170.         break;
  171.     }
  172.  
  173.     if (NULL == cur)
  174.         return TRUE;
  175.  
  176.     if (count < 0) {
  177.         count = -count;
  178.     }
  179.  
  180.     next = (backwards) ? cur->prev : cur->next;
  181.  
  182.     while (next && count) {
  183.         cur  = next;
  184.         next = (backwards) ? cur->prev : cur->next;
  185.         --count;
  186.     }
  187.  
  188.     list->cur = cur;
  189.     return (next == NULL);
  190. }
  191.  
  192. long dl_tell(list)
  193. /*****************************************************************************
  194.  * returns the index of the current item in the list.
  195.  ****************************************************************************/
  196.     register DlList *list;
  197. {
  198.     register DllHeader *cur = list->head;
  199.     register long       idx    = 0;
  200.  
  201.     while (cur && cur != list->cur) {
  202.         ++idx;
  203.         cur = cur->next;
  204.     }
  205.  
  206.     return idx;
  207. }
  208.